//
//  MLXSaoYiSaoViewController.m
//  Pods-MLXCamera
//
//  Created by SY on 2019/2/20.
//

#import "MLXSaoYiSaoViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "UIImage+mask.h"
// 距顶部高度
#define Top_Height 0.2*[UIScreen mainScreen].bounds.size.height
// 中间View的宽度
#define MiddleWidth 0.8*[UIScreen mainScreen].bounds.size.width

static NSString *saoText = @"将二维码/条形码放入框内，即可自动扫描";


@interface MLXSaoYiSaoViewController ()<AVCaptureMetadataOutputObjectsDelegate>
{
    bool _canOpen;
    int num;
    BOOL upOrdown;
    NSTimer * timer;
    BOOL bNeedScanResult;
    BOOL bHadAutoVideoZoom;
    
}
@property (strong,nonatomic)AVCaptureDevice * device;
@property (strong,nonatomic)AVCaptureDeviceInput * input;
@property (strong,nonatomic)AVCaptureMetadataOutput * output;
@property (strong,nonatomic)AVCaptureSession * session;
@property (strong,nonatomic)AVCaptureVideoPreviewLayer * preview;
@property(nonatomic,strong)  AVCaptureStillImageOutput *stillImageOutput;
@property (nonatomic, retain) UIImageView * line;
@property (nonatomic, assign) CGPoint centerPoint;
/*** 专门用于保存描边的图层 ***/
@property (nonatomic,strong) CALayer *containerLayer;
@property(nonatomic,strong) UIView *videoPreView;
@end

@implementation MLXSaoYiSaoViewController

-(instancetype)initWithImagTintColorColor:(UIColor *)imagTintColorColor completeBlock:(void(^)(NSString *stringValue,MLXSaoYiSaoViewController *vc))completeBlock{
    if (self = [super init]) {
        _canOpen = NO;
        self.imagTintColorColor = imagTintColorColor;
        self.completeBlock = completeBlock;
    }
    return self;
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        _canOpen = NO;
    }
    return self;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    UIView *videoView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame))];
    videoView.backgroundColor = [UIColor clearColor];
    [self.view insertSubview:videoView atIndex:0];
    _videoPreView = videoView;
    if (self.navigationController) {
        self.navigationController.navigationBar.hidden = YES;
    }
    self.view.backgroundColor = [UIColor blackColor];
    [self creatBackGroundView];
    [self creatUI];
    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
}
-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}
-(void)viewWillAppear:(BOOL)animated{
    [self setupCamera];
    if (self.navigationController) {
        self.navigationController.navigationBar.hidden = YES;
    }
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    if (self.navigationController) {
        self.navigationController.navigationBar.hidden = NO;
    }
    [timer invalidate];
    timer = nil;
    [_session stopRunning];
}
-(void)start{
    self->timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(lineAnimation) userInfo:nil repeats:YES];
    [self->_session startRunning];
    self->bNeedScanResult = YES;
    self->bHadAutoVideoZoom = NO;
    [self setVideoScale:1];
}
-(void)lineAnimation{
    CGFloat leadSpace = ([UIScreen mainScreen].bounds.size.width - MiddleWidth)/ 2;
    if (upOrdown == NO) {
        num ++;
        _line.frame = CGRectMake(leadSpace, Top_Height+2*num, MiddleWidth, 12);
        if (2*num >= MiddleWidth-12) {
            upOrdown = YES;
            _line.image = [self pathForResource:@"SaoYiSao_Icon_SaoLineOn"];
        }
    }else {
        num --;
        _line.frame = CGRectMake(leadSpace, Top_Height+2*num, MiddleWidth, 12);
        if (num == 0) {
            upOrdown = NO;
            _line.image = [self pathForResource:@"SaoYiSao_Icon_SaoLine"];
        }
    }
}
-(UIImage *)pathForResource:(NSString *)name{
    NSBundle *bundle = [NSBundle bundleForClass:self.class];
    NSString *img_path = [bundle pathForResource:name ofType:@"png" inDirectory:@"MLXCamera.bundle"];
    UIImage *image = [UIImage imageWithContentsOfFile:img_path];
    if (!image) {
        img_path = [bundle pathForResource:name ofType:@"png" inDirectory:@"MLXCamera_SaoYiSao.bundle"];
        image = [UIImage imageWithContentsOfFile:img_path];
    }
    if (self.imagTintColorColor) {
        image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    }
    return image;
}
-(void)backAction{
    UIViewController *vc = [self.navigationController popViewControllerAnimated:YES];
    if (!vc) {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
}
- (void)setupCamera{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // Device
        if (!self->_device) {
            self->_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
            // Input
            self->_input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
            
            // Output
            self->_output = [[AVCaptureMetadataOutput alloc]init];
            [self->_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
            
            self->_stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
            NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:
                                            AVVideoCodecJPEG, AVVideoCodecKey,
                                            nil];
            [self->_stillImageOutput setOutputSettings:outputSettings];
            
            // Session
            self->_session = [[AVCaptureSession alloc]init];
            [self->_session setSessionPreset:AVCaptureSessionPresetHigh];
            if ([self->_session canAddInput:self.input]){
                [self->_session addInput:self.input];
                self->_canOpen = YES;
            }else{
                dispatch_async(dispatch_get_main_queue(), ^{
                    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:@"打开相机权限" preferredStyle:UIAlertControllerStyleAlert];
                    UIAlertAction *action = [UIAlertAction actionWithTitle:@"取消"
                                                                     style:UIAlertActionStyleCancel
                                                                   handler:^(UIAlertAction *action){
                                                                       [self backAction];
                                                                   }];
                    [alertController addAction:action];
                    UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"去设置"
                                                                      style:UIAlertActionStyleDefault
                                                                    handler:^(UIAlertAction *action){
                                                                        NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                                                                        if([[UIApplication sharedApplication] canOpenURL:url]) {
                                                                            [[UIApplication sharedApplication] openURL:url];
                                                                        }
                                                                        [self backAction];
                                                                    }];
                    [alertController addAction:action2];
                    [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
                });
            }
            if (self->_canOpen) {
                if ([self->_session canAddOutput:self.output]){
                    [self->_session addOutput:self.output];
                }
                // 条形码/二维码
                self->_output.metadataObjectTypes =[NSArray arrayWithObjects:AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode, nil];
                // 只支持二维码
                //                _output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];
                
                // Preview
                self->_preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session];
                self->_preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
                dispatch_async(dispatch_get_main_queue(), ^{
                    //回到主线程
                    self->_preview.frame =CGRectMake(0,0,[UIScreen mainScreen].bounds.size.width,[UIScreen mainScreen].bounds.size.height);
//                    [self.view.layer insertSublayer:self.preview atIndex:0];
                     [self->_videoPreView.layer insertSublayer:self.preview atIndex:0];
                     [self.containerLayer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
                });
            }
            
            if ([self->_session canAddOutput:self->_stillImageOutput]) {
                [self->_session addOutput:self->_stillImageOutput];
            }
        }
        // Start
        if (self->_canOpen) {
            dispatch_async(dispatch_get_main_queue(), ^{
                //回到主线程
                self->timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(lineAnimation) userInfo:nil repeats:YES];
                [self->_session startRunning];
                self->bNeedScanResult = YES;
                self->bHadAutoVideoZoom = NO;
                [self setVideoScale:1];
            });
        }
    });
}
#pragma mark -
#pragma mark  -- -- -- -- -- AVCapture Metadata Output Objects Delegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
    if (!bNeedScanResult) {
        return;
    }
    
    bNeedScanResult = NO;
    NSString *stringValue;
    if ([metadataObjects count] >0){
         bNeedScanResult = NO;
        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
        stringValue = metadataObject.stringValue;
    }else{
        bNeedScanResult = YES;
        return;
    }
    
    if (_isAutoVideoZoom && !bHadAutoVideoZoom) {
        AVMetadataMachineReadableCodeObject *obj = (AVMetadataMachineReadableCodeObject *)[self.preview transformedMetadataObjectForMetadataObject:metadataObjects.lastObject];
        [self changeVideoScale:obj];
        bNeedScanResult = YES;
        bHadAutoVideoZoom  =YES;
        return;
    }
    [self stopRunning];
    !self.completeBlock ?: self.completeBlock(stringValue,self);
}
#pragma mark -
#pragma mark  -- -- -- -- -- MakeView
-(void)stopRunning{
    [_session stopRunning];
    [timer invalidate];
    timer = nil;
   
}
- (void)creatBackGroundView{
    UIImageView *maskView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
    maskView.image = [UIImage maskImageWithMaskRect:maskView.frame clearRect:CGRectMake(([UIScreen mainScreen].bounds.size.width-MiddleWidth)/2, Top_Height, MiddleWidth, MiddleWidth)];
    [self.view addSubview:maskView];
}

- (void)creatUI{
    UIButton * backBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    BOOL IsiPhoneX  = (((int)(([UIScreen mainScreen].bounds.size.height/[UIScreen mainScreen].bounds.size.width)*100) == 216)?YES:NO);
    CGFloat y = IsiPhoneX ? 40 : 24;
    backBtn.frame = CGRectMake(10, y, 32, 32);
    [backBtn setImage:[[self pathForResource:@"anniu"] imageWithRenderingMode:
                       UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
    [backBtn addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:backBtn];
    
    UILabel * labIntroudction= [[UILabel alloc] initWithFrame:CGRectMake(0, Top_Height+MiddleWidth + 20, [UIScreen mainScreen].bounds.size.width, 35)];
    labIntroudction.numberOfLines=2;
    labIntroudction.text= saoText;
    labIntroudction.textAlignment = NSTextAlignmentCenter;
    labIntroudction.textColor = [UIColor whiteColor];
    labIntroudction.font = [UIFont systemFontOfSize:14];
    [self.view addSubview:labIntroudction];
    
    CGFloat leadSpace = ([UIScreen mainScreen].bounds.size.width - MiddleWidth)/ 2;
    UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(leadSpace, Top_Height, MiddleWidth, MiddleWidth)];
    if (self.imagTintColorColor) {
        imageView.tintColor = self.imagTintColorColor;
    }
    imageView.image = [self pathForResource:@"SaoYiSao_Icon_SaoYiSao"];
    [self.view addSubview:imageView];
    
    upOrdown = NO;
    num =0;
    _line = [[UIImageView alloc] initWithFrame:CGRectMake(leadSpace, Top_Height, MiddleWidth, 12)];
    if (self.imagTintColorColor) {
        _line.tintColor = self.imagTintColorColor;
    }
    _line.image = [self pathForResource:@"SaoYiSao_Icon_SaoLine"];
    _line.contentMode = UIViewContentModeScaleToFill;
    [self.view addSubview:_line];
    
    if (self.isIdentifyPhoto) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.titleLabel.font = [UIFont systemFontOfSize:16];
        [button setTitle:@"相册" forState:UIControlStateNormal];
        [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(identifyPhotoClick) forControlEvents:UIControlEventTouchUpInside];
        [self.view  addSubview:button];
        button.frame = CGRectMake([UIScreen mainScreen].bounds.size.width - 50 - 10, y - 5, 40, 40);
        
    }
}
-(void)identifyPhotoClick{
    !self.identifyPhotoBlock ?: self.identifyPhotoBlock(self);
}
-(void)incomIdentifyImage:(UIImage *)image{
    if (!image) return;
    CIContext *context = [[CIContext alloc] init];
    // 1.创建一个探测器
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:context options:@{CIDetectorAccuracy: CIDetectorAccuracyLow}];
    // 2.直接开始识别图片,获取图片特征
    CIImage *imageCI = [[CIImage alloc] initWithImage:image];
    NSArray *features = [detector featuresInImage:imageCI];
    CIQRCodeFeature *codef = (CIQRCodeFeature *)features.firstObject;
    if (codef.messageString.length) {
        [self stopRunning];
        !self.completeBlock ?: self.completeBlock(codef.messageString,self);
    }
}
- (void)changeVideoScale:(AVMetadataMachineReadableCodeObject *)objc
{
    NSArray *array = objc.corners;
    CGPoint point = CGPointZero;
    // 把字典转换为点，存在point里，成功返回true 其他false
    CGPointMakeWithDictionaryRepresentation((__bridge CFDictionaryRef)array[0], &point);

    CGPoint point2 = CGPointZero;
    CGPointMakeWithDictionaryRepresentation((__bridge CFDictionaryRef)array[2], &point2);

    self.centerPoint = CGPointMake((point.x + point2.x) / 2, (point.y + point2.y) / 2);
    CGFloat scace = 150 / (point2.x - point.x); //当二维码图片宽小于150，进行放大
    [self setVideoScale:scace];
    return;
}

- (void)drawLine:(AVMetadataMachineReadableCodeObject *)objc
{
    
    NSArray *array = objc.corners;
    
    // 1.创建形状图层, 用于保存绘制的矩形
    CAShapeLayer *layer = [[CAShapeLayer alloc] init];
    
    // 设置线宽
    layer.lineWidth = 2;
    // 设置描边颜色
    layer.strokeColor = [UIColor greenColor].CGColor;
    layer.fillColor = [UIColor clearColor].CGColor;
    
    // 2.创建UIBezierPath, 绘制矩形
    UIBezierPath *path = [[UIBezierPath alloc] init];
    CGPoint point = CGPointZero;
    int index = 0;
    
    CFDictionaryRef dict = (__bridge CFDictionaryRef)(array[index++]);
    // 把点转换为不可变字典
    // 把字典转换为点，存在point里，成功返回true 其他false
    CGPointMakeWithDictionaryRepresentation(dict, &point);
    
    // 设置起点
    [path moveToPoint:point];
    
    // 2.2连接其它线段
    for (int i = 1; i<array.count; i++) {
        CGPointMakeWithDictionaryRepresentation((__bridge CFDictionaryRef)array[i], &point);
        [path addLineToPoint:point];
    }
    // 2.3关闭路径
    [path closePath];
    layer.path = path.CGPath;
    // 3.将用于保存矩形的图层添加到界面上
    [self.containerLayer addSublayer:layer];
}
- (AVCaptureConnection *)connectionWithMediaType:(NSString *)mediaType fromConnections:(NSArray *)connections{
    for ( AVCaptureConnection *connection in connections ) {
        for ( AVCaptureInputPort *port in [connection inputPorts] ) {
            if ( [[port mediaType] isEqual:mediaType] ) {
                return connection;
            }
        }
    }
    return nil;
}
- (void)setVideoScale:(CGFloat)scale
{
    scale = 1;
    [_input.device lockForConfiguration:nil];
    
    AVCaptureConnection *videoConnection = [self connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self stillImageOutput] connections]];
    CGFloat maxScaleAndCropFactor = ([[self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo] videoMaxScaleAndCropFactor])/16;
    
    if (scale > maxScaleAndCropFactor)
        scale = maxScaleAndCropFactor;
    
    CGFloat zoom = scale / videoConnection.videoScaleAndCropFactor;
    videoConnection.videoScaleAndCropFactor = scale;
    
    [_input.device unlockForConfiguration];
    
    CGAffineTransform transform = _videoPreView.transform;
    if (scale == 1) {
        _videoPreView.transform = CGAffineTransformScale(transform, zoom, zoom);
        CGRect rect = self.view.frame;
        rect.origin = CGPointZero;
        _videoPreView.frame = rect;
    } else {
        CGFloat x = _videoPreView.center.x - self.centerPoint.x;
        CGFloat y = _videoPreView.center.y - self.centerPoint.y;
        CGRect rect = _videoPreView.frame;
        rect.origin.x = rect.size.width / 2.0 * (1 - scale);
        rect.origin.y = rect.size.height / 2.0 * (1 - scale);
        rect.origin.x += x * zoom;
        rect.origin.y += y * zoom;
        rect.size.width = rect.size.width * scale;
        rect.size.height = rect.size.height * scale;
        [UIView animateWithDuration:.5f animations:^{
            self->_videoPreView.transform = CGAffineTransformScale(transform, zoom, zoom);
            self->_videoPreView.frame = rect;
        } completion:^(BOOL finished) {
        }];
    }
}

-(void)setNeedAutoVideoZoom:(BOOL)isAutoVideoZoom
{
    _isAutoVideoZoom = isAutoVideoZoom;
}

- (CALayer *)containerLayer
{
    if (_containerLayer == nil) {
        _containerLayer = [[CALayer alloc] init];
    }
    return _containerLayer;
}
@end
